#ifndef LHC_ISTREAM_H_INCLUDED_
#define LHC_ISTREAM_H_INCLUDED_

#include "Endian.h"
#include <boost/cstdint.hpp>
#include <vector>

namespace lhcutils
{

struct SeekOrigin
{
	enum Value
	{
		Begin,
		Current,
		End
	};
};

class IStream
{
public:
	virtual bool CanRead() = 0;
	virtual bool CanWrite() = 0;
	virtual bool CanSeek() = 0;
	
	// Throws: IoException, NotSupportedException, other ProgrammerErrorException
	virtual boost::int64_t GetPosition() = 0;
	boost::int64_t Tell();

	// Throws: IoException, NotSupportedException, other ProgrammerErrorException
	virtual void SetPosition(boost::int64_t newPosition, SeekOrigin::Value origin) = 0;
	void Seek(boost::int64_t newPosition, SeekOrigin::Value origin); // synonym for SetPosition

	// Throws: IoException
	virtual void Flush() = 0;

	// Throws: IoException, NotSupportedException, other ProgrammerErrorException
	virtual size_t Read(void* buffer, size_t count) = 0;
	std::vector<boost::uint8_t> ReadFull(size_t count);

	boost::uint8_t ReadByte();
	boost::int32_t ReadInt32(Endianness::Value endianness);
	boost::int32_t ReadInt32Le();
	boost::int32_t ReadInt32Be();
	boost::uint32_t ReadUint32(Endianness::Value endianness);
	boost::uint32_t ReadUint32Le();
	boost::uint32_t ReadUint32Be();
	boost::int64_t ReadInt64(Endianness::Value endianness);
	boost::int64_t ReadInt64Le();
	boost::int64_t ReadInt64Be();

	// Throws: IoException, NotSupportedException, other ProgrammerErrorException
	virtual void Write(const void* buffer, size_t count) = 0;
	void Write(const std::vector<boost::uint8_t>& buffer);

	void WriteInt32(boost::int32_t value, Endianness::Value endianness);
	void WriteInt32Le(boost::int32_t value);
	void WriteInt32Be(boost::int32_t value);
	void WriteInt64(boost::int64_t value, Endianness::Value endianness);
	void WriteInt64Le(boost::int64_t value);
	void WriteInt64Be(boost::int64_t value);

	virtual void Close() = 0;
	virtual ~IStream();
};

}

#endif

/*
 Copyright 2011 Greg Najda

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
